package com.bejoy.coolatin.custom;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;

/**
 * 来自：http://blog.csdn.net/listening_music/article/details/7192629
 * 瀑布流滚动容器，实现瀑布流实际上就是利用 ScrollView 的滚动机制，判断位置状态来实现加载<br/>
 * 本类继承 ScrollView，其中有一个 getView 方法，以及 view 成员变量，这两个内容指引的是<br/>
 * ScrollView 的内部子容器，由于 ScrollView 有且只有一个子容器，因此通过 getChild(0) 来获取。<br/>
 * 瀑布流算法规则：<br/>
 * <ol>
 * <li>监听ScrollView的OnTouchListener，进行拖拽监听</li>
 * <li>当触摸拖拽事件抬起的时候，发送消息进行拖拽位置的计算</li>
 * <li>当拖拽到底部的时候，调用 自定义的 OnScrollListener 的 onBottom()</li>
 * <li>计算拖拽位置算法，当前ScrollView自身有一个高度，内部子容器有一个测量高度<br/>
 * 同时ScrollView还有一个 getScrollY() 返回滚动的相对于子容器的位置</li>
 * <li>判断到最后的位置，即可调用回调，进行内容的加载</li>
 * </ol>
 * <br/>
 * 判断是否移动到底部的算法：<br/>
 * <font color="red"></font><br/>
 * 图示如下:<br/>
 * 
 * <pre>
 *             ScrollView与内部子容器的关系实例
 *                             view 子容器
 * -------->                 ----------------
 *   |                       |              |
 *   |                       |              |  <- 被移动上去看不见的内容
 *   |                       |              |  <- 此处的高度可以利用 ScrollView.getScrollY() 来获取
 *   |                       ＝＝＝＝＝＝＝＝＝＝
 *   |                       [              ]
 *   |                       [              ]
 * view.getMeasuredHeight()  [              ]  <-  ScrollView
 *   |                       [              ]  <-    ScrollView.getHeight() 就是[] 的范围高度
 *   |                       [              ]  <font color="red">ScrollView的高度不是内部控件的高度</font>
 *   |                       ＝＝＝＝＝＝＝＝＝＝
 *   |                       |              |
 *   |                       |              |
 *   |                       |              |
 *   |                       |              |
 * ---------->               ----------------
 * 
 * </pre>
 * 
 */
public class LazyScrollView extends ScrollView {

	/**
	 * 声明标志位
	 */
	private static final String tag = "LazyScrollView";

	/**
	 * 声明处理器对象
	 */
	private Handler handler;

	/**
	 * 声明View对象
	 */
	private View view;

	public LazyScrollView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public LazyScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public LazyScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}
	
	/**
	 * 这个获得总的高度
	 */
    public int computeVerticalScrollRange() {
        return super.computeHorizontalScrollRange();
    }

    /**
     * 计算滚到范围
     */
    public int computeVerticalScrollOffset() {
        return super.computeVerticalScrollOffset();
    }
    
    /**
     * 初始化触摸屏事件
     */
    private void init() {

        this.setOnTouchListener(onTouchListener);
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // process incoming messages here
                super.handleMessage(msg);
                switch (msg.what) {
                    case 1:
                        // 此处是瀑布流判断是否到最下方的关键点
                        // view.getMeasuredHeight() 方法返回的是view这个容器完整的高度尺寸
                        // getScrollY() 是当前 ScrollView 滚动view的位置
                        // getHeight() 是当前ScrollView的高度，注意，当前ScrollView的getHeight()是自己的高度限制
                        //             并不是view的高度
                        if (view.getMeasuredHeight() <= getScrollY() + getHeight()) {
                            if (onScrollListener != null) {
                                onScrollListener.onBottom();
                            }

                        } else if (getScrollY() == 0) {
                            if (onScrollListener != null) {
                                onScrollListener.onTop();
                            }
                        } else {
                            if (onScrollListener != null) {
                                onScrollListener.onScroll();
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        };

        /*

        ScrollView与内部子容器的关系实例

                            view 子容器
        ---------->       ----------------
        |                 |              |
        |                 |              |  <- 被移动上去看不见的内容
        |                 |              |  <- 此处的高度可以利用 ScrollView.getScrollY() 来获取
        |                 ＝＝＝＝＝＝＝＝＝＝
        |                 [              ]
        |                 [              ]
view.getMeasuredHeight()  [              ]  <-  ScrollView
        |                 [              ]  <-    ScrollView.getHeight() 就是[] 的范围高度
        |                 [              ]
        |                 ＝＝＝＝＝＝＝＝＝＝
        |                 |              |
        |                 |              |
        |                 |              |
        |                 |              |
        ---------->       ----------------

         */


    }

    /**
     * 触摸事件，这个是在触摸抬起的时候，发送事件消息，进行检查
     */
    OnTouchListener onTouchListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    break;
                case MotionEvent.ACTION_UP:
                    if (view != null && onScrollListener != null) {
                        handler.sendMessageDelayed(handler.obtainMessage(1), 200);
                    }
                    break;
                default:
                    break;
            }
            return false;
        }

    };

    /**
     * 获得参考的View，主要是为了获得它的MeasuredHeight，然后和滚动条的ScrollY+getHeight作比较。
     */
    public void getView() {
        this.view = getChildAt(0);
        if (view != null) {
            init();
        }
    }

    /**
     * 定义瀑布流滚动接口
     *
     * @author admin
     */
    public interface OnScrollListener {
        /**
         * 滚动到底部的时候进行回调
         */
        void onBottom();

        /**
         * 滚动到顶部的时候进行回调
         */
        void onTop();

        /**
         * 滚动时进行回调
         */
        void onScroll();
    }

    /**
     * 滚动回调接口
     */
    private OnScrollListener onScrollListener;

    /**
     * 设置滚动回调接口
     * @param onScrollListener OnScrollListener
     */
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }

}
